import { matlabFolderName } from '@/config';
import { getUuid, getRandomLetter } from '@/utils/util.js';
import Vue from 'vue';
import {
  userProjectDelete,
  userProjectGetAll,
  userProjectSave,
  userProjectUpdate,
  userProjectRun,
  downloadOss
} from '@/api/userProject';
import { getObjectUrl, putObject, deleteObject, deleteObjectMulti } from '@/utils/aliOss';
// import { PanguPy, KaitianPy } from '@/pycode';
import { processVar } from '@/utils/variable';
import { MessageBox } from 'element-ui';
// import { createFunctionLibrary } from '@/api/userProjectLibrary';
// import { stubTrue } from 'lodash-es';

const matlab = {
  namespaced: true,
  state: {
    isShowToolbar: true, // 是否显示工具条
    toolbarShowTab: 'main', // 当前显示的tab
    originTreeData: [], // 原数据
    showTreeData: [], // 展示节点
    fileList: [], // 最近使用的文件记录
    matlabFolderName, // OSS存放目录
    username: '', // 等有账号系统后修改（用户ID，唯一）
    breadPath: '', // 面包屑导航路径（用户ID，唯一）
    breadcrumb: [], // 面包屑导航数据
    editorFiles: [], // 编辑器tabs数据
    editorFilesId: '', // 当前展示文件ID
    loadingResult: false, // 是否显示结果
    innerHeight: 0, // window的高度
    defaultExpanded: [], // 默认展开节点,
    navigator: { // 导航栏
      front_navList: [{
        breadcrumb: []
      }], // 前进历史栈
      back_navList: [{
        breadcrumb: []
      }], // 后退历史栈
      front_pointer: 0,
      back_pointer: 0
    },
    downloadFile: null, // 是否可点击标题栏下载键
    isUploadFile: false, // 上传文件中
    isShowDrawList: false, // 是否显示绘图目录
    isShowChooseVariable: false, // 是否显示选择变量窗口
    isShowMatlabImg: [], // 是否显示运行返回图片结果弹窗
    isImgReuseWindow: true, // 是否重用窗口
    matlabImgJson: [], // 运行返回图片html展示
    matlabImgJsonIndex: [], // 运行返回图片html展示下标
    termWrite: null, // 命令行显示
    termCall: null, // 命令行调用
    termArray: {
      userId: 0,
      saveArray: [], // 历史命令存储
      pointer: 0 // 命令最后一条的指针
    }, // 命令行队列
    tmpTermWrite: '',
    variableArray: [], // 工作区变量
    termProject: null, // 命令行项目
    selectedVars: [], // 选择的工作区变量
    insertLines: 0, // 代码翻译时插入到用户代码前的行数,
    uploadNode: null, // 文件上传的目录,
    base64Img: '', // 图片base64数据,
    showBase64Img: false, // 是否显示base64图片
    isexchange: 0,
    projectPublicLayer: {} // 变量设置为存放每个project使用的publicLayer的，删除时需要将对应的项目删除
  },

  getters: {
    // 判断Toolbar高度
    getMarginTop: (state) => {
      if (state.isShowToolbar) {
        return '121px';
      } else {
        return '28px';
      }
    },
    // 获取内容展示高度
    getContentHeight: (state) => {
      if (!state.innerHeight) {
        state.innerHeight = window.innerHeight;
      }
      if (state.isShowToolbar) {
        return (state.innerHeight - 147) + 'px';
      } else {
        return (state.innerHeight - 54) + 'px';
      }
    },
    // 获取变量信息
    getVariables: (state) => {
      return state.variableArray;
    },
    getProcessedVariables: (state) => {
      return processVar(state.variableArray);
    },
    // 获取历史命令
    getTermWrite: (state) => {
      if (state.termArray.pointer === state.termArray.saveArray.length) return state.tmpTermWrite;
      else return state.termArray.saveArray[state.termArray.pointer];
    },
    // 是否为根目录（根目录只可创建文件夹，不可直接创建文件）
    isRootFolder: (state) => state.breadcrumb.length === 0,
    // 判断目录可退
    isShowBreadBack: (state) => state.navigator.pointer <= 0,
    // 判断目录可前进
    isShowBreadForward: (state) => {
      return state.navigator.pointer >= state.navigator.navList.length - 1;
    }
  },

  mutations: {
    // 从localStorage中获取数据
    SET_DATA: (state, payload) => {
      state.isShowToolbar = payload.isShowToolbar;
      state.originTreeData = payload.originTreeData;
      state.showTreeData = payload.showTreeData;
      state.matlabFolderName = payload.matlabFolderName;
      state.defaultExpanded = payload.defaultExpanded;
      state.username = payload.username;
      // state.breadPath = payload.breadPath;
      state.fileList = payload.fileList;
      state.editorFilesId = payload.editorFilesId;
      state.editorFiles = payload.editorFiles;
      state.toolbarShowTab = payload.toolbarShowTab;
      state.tmpTermWrite = payload.tmpTermWrite;
      state.variableArray = payload.variableArray || [];
      state.projectPublicLayer = payload.projectPublicLayer || {};
      // state.termArray = {
      //   userId: 0,
      //   saveArray: [],
      //   pointer: 0
      // };
      // if (state.editorFiles.length > 0) {
      //   state.toolbarShowTab = 'editor';
      // } else {
      //   state.toolbarShowTab = payload.toolbarShowTab;
      // }
    },
    // 设置uid
    setUid(state, id) {
      state.username = id;
      state.breadPath = id;
    },
    // 窗口变化设置高度
    resetInnerHeight: (state) => {
      state.innerHeight = window.innerHeight;
    },
    // 更换toolbar
    changeToolbar: (state, payload) => {
      state.toolbarShowTab = payload;
    },
    // 隐藏工具条
    isHideToolbar: (state) => {
      if (!state.isShowToolbar && state.toolbarShowTab !== '') {
        state.toolbarShowTab = '';
      }
    },
    // 展示/隐藏 工具条
    toolbarCollapse: (state) => {
      if (state.isShowToolbar) {
        state.toolbarShowTab = '';
      } else {
        state.toolbarShowTab = state.toolbarShowTab === '' ? 'main' : state.toolbarShowTab;
      }
      state.isShowToolbar = !state.isShowToolbar;
    },
    // 设置项目数的数据源
    setTreeData: (state, payload) => {
      state.originTreeData = payload;
      state.showTreeData = payload;
    },
    // 展示根目录
    resetTreeData: (state) => {
      // console.log('resetTreeData');
      state.showTreeData = state.originTreeData;
      state.breadcrumb = [];
      setBreadPath(state);
      addNavigator_back(state, {
        breadcrumb: state.breadcrumb,
        showTreeData: state.showTreeData
      });
    },
    // 设置面包屑导航数据
    resetBreadcrumb: (state, payload) => {
      const { type, item, index, bread } = payload;
      // console.log('resetBreadcrub', type, item, index, bread);
      state.navigator.front_navList = [{ breadcrumb: [] }];
      state.navigator.front_pointer = 0;
      state.showTreeData = item.children;
      if (type === 'delete') {
        state.breadcrumb.splice(index + 1, state.breadcrumb.length - index + 1);
      } else if (type === 'change') {
        // console.log(JSON.stringify(state.breadcrumb));
        state.breadcrumb.splice(index, state.breadcrumb.length - index);
        // console.log(JSON.stringify(state.breadcrumb));
        state.breadcrumb.push(...bread);
      } else {
        state.breadcrumb.push(...bread);
      }
      setBreadPath(state);
      addNavigator_back(state, {
        breadcrumb: state.breadcrumb,
        showTreeData: state.showTreeData
      });
    },
    // 向上一级
    breadcrumbBack: (state) => {
      if (state.breadcrumb.length > 0) {
        state.breadcrumb.pop();
        if (state.breadcrumb.length > 0) {
          state.showTreeData = state.breadcrumb.at(-1).children;
        } else {
          state.showTreeData = state.originTreeData;
        }
        setBreadPath(state);
        state.navigator.front_navList = [{ breadcrumb: [] }];
        state.navigator.front_pointer = 0;
        addNavigator_back(state, {
          breadcrumb: state.breadcrumb,
          showTreeData: state.showTreeData
        });
      }
    },
    // 命令行前进后退
    moveTermArray: (state, data) => {
      if (state.termArray.saveArray.length === 0 || state.termArray.userId !== state.username) {
        state.termArray = {
          userId: 0,
          saveArray: [],
          pointer: 0
        };
        if (JSON.parse(localStorage.getItem(state.username.toString() + 'termArray')) !== null) state.termArray = JSON.parse(localStorage.getItem(state.username.toString() + 'termArray'));
      }
      let index = state.termArray.pointer;
      if (data.payload === 'f_command') {
        if (index >= 0) {
          if (index === state.termArray.saveArray.length) state.tmpTermWrite = data.TermWrite;
          else if (state.termArray.saveArray[state.termArray.pointer] !== data.TermWrite) {
            state.tmpTermWrite = data.TermWrite;
            state.termArray.pointer = state.termArray.saveArray.length;
            index = state.termArray.pointer;
          }
          if (index > 0) state.termArray.pointer--;
        }
      } else {
        if (index < state.termArray.saveArray.length) {
          if (state.termArray.saveArray[state.termArray.pointer] !== data.TermWrite) {
            state.tmpTermWrite = data.TermWrite;
            state.termArray.pointer = state.termArray.saveArray.length;
          } else state.termArray.pointer++;
        }
      }
    },
    // 命令行内部数组更新
    updateTempArray: (state, payload) => {
      if (state.termArray.saveArray.length === 0 || state.termArray.userId !== state.username) {
        state.termArray = {
          userId: 0,
          saveArray: [],
          pointer: 0
        };
        if (JSON.parse(localStorage.getItem(state.username.toString() + 'termArray')) !== null) state.termArray = JSON.parse(localStorage.getItem(state.username.toString() + 'termArray'));
      }
      state.termArray.saveArray.push(payload);
    },
    // 命令行内部的索引更新
    updateTermArrayPointer: (state) => {
      state.termArray.pointer = state.termArray.saveArray.length;
      state.termArray.userId = state.username;
      localStorage.setItem(state.username.toString() + 'termArray', JSON.stringify(state.termArray));
    },
    // 导航栏前进后退
    moveBread: (state, payload) => {
      // console.log('moveBread');
      // console.log('state.back_navList', JSON.stringify(state.navigator.back_navList));
      // console.log('state.breadcrumb', JSON.stringify(state.breadcrumb));
      if (payload === 'back') {
        if (state.navigator.back_pointer > 0) {
          state.navigator.back_pointer--;
          // console.log('before pop, list', JSON.stringify(state.navigator.back_navList));
          const data = state.navigator.back_navList.pop();
          // console.log('state.back_navList', JSON.stringify(state.navigator.back_navList));
          state.navigator.front_navList.push(data);
          state.navigator.front_pointer++;
          // console.log('after pop, list', JSON.stringify(state.navigator.back_navList));
          state.breadcrumb = JSON.parse(JSON.stringify(state.navigator.back_navList.at(-1).breadcrumb));
          // console.log(JSON.stringify(state.breadcrumb));
          if (state.navigator.back_pointer === 0) {
            state.showTreeData = state.originTreeData;
          } else {
            state.showTreeData = state.navigator.back_navList.at(-1).showTreeData;
          }
        }
      } else {
        if (state.navigator.front_pointer > 0) {
          state.navigator.front_pointer--;
          const data = state.navigator.front_navList.pop();
          state.breadcrumb = JSON.parse(JSON.stringify(data.breadcrumb));
          state.navigator.back_navList.push(data);
          state.navigator.back_pointer++;
          if (state.breadcrumb.length === 0) {
            state.showTreeData = state.originTreeData;
          } else {
            state.showTreeData = data.showTreeData;
          }
        }
      }
      // console.log('moveBread end');
      // console.log('state.back_navList', JSON.stringify(state.navigator.back_navList));
      // console.log('state.breasdcrum', JSON.stringify(state.breadcrumb));
      setBreadPath(state);
    },
    // 筛选文件
    setFileList: (state) => {
      const data = {
        fileIds: []
      };
      getProjectFiles(state, state.originTreeData, data);
      state.fileList = state.fileList.filter(item => {
        return data.fileIds.includes(item.id);
      });
    },
    // 添加节点
    append: (state, payload) => {
      const { nodeType, type, data } = payload;
      const newChild = {
        isEditName: true,
        id: getRandomLetter() + getUuid(16), // 阿里云函数命名首位必须为字母
        label: '',
        isFirstBuild: true,
        hadRun: false
      };
      if (type === 'buildFolder' || type === 'buildRootFolder') {
        newChild.children = [];
        newChild.isFile = false;
        if (type === 'buildRootFolder') { // 用于新建工程时的图标识别，后续会删掉
          newChild.tmpProjectIcon = true;
        }
      } else {
        newChild.isFile = true;
      }
      if (nodeType === 'father') {
        if (state.breadcrumb.length > 0) {
          const bread = state.breadcrumb[0];
          newChild.path = bread.path ? `${bread.path}/${bread.label}` : bread.label;
          newChild.fatherId = bread.projectId || bread.fatherId;
        }
        state.showTreeData.unshift(newChild);
        return;
      }
      newChild.fatherId = data.projectId || data.fatherId;
      newChild.path = data.path ? `${data.path}/${data.label}` : data.label;
      newChild.isEditName = false;
      data.children.unshift(newChild);
      Vue.nextTick(() => {
        newChild.isEditName = true;
      });
    },
    // 删除节点
    remove: (state, payload) => {
      const { node, data } = payload;
      const parent = node.parent;
      const children = parent.data.children || parent.data;
      const index = children.findIndex((d) => d.id === data.id);
      children.splice(index, 1);
    },
    // 修改文件名
    editName: (state, payload) => {
      if (Object.keys(payload).includes('isEditName')) {
        payload.isEditName = true;
      } else {
        Vue.set(payload, 'isEditName', true);
      }
    },
    // 清空编辑器
    clearEditorFiles: (state) => {
      state.editorFiles = [];
      state.editorFilesId = '';
    },
    // 设置编辑器tab
    setEditorFiles: (state, payload) => {
      if (payload.type === 'add') {
        state.editorFiles.push(payload.data);
        state.editorFilesId = state.editorFiles[state.editorFiles.length - 1].id;
        state.toolbarShowTab = payload.data.display === 'file' ? 'editor' : 'variable';
      } else if (payload.type === 'remove') {
        removeFromEditor(state, payload.data.id);
      }
    },
    // 设置localstorage内的editorFiles值
    setLocalEditorFiles: (state) => {
      localStorage.setItem(`editorFiles`, JSON.stringify(state.editorFiles));
    },
    // 设置编辑器当前显示tab
    setEditFileId: (state, payload) => {
      state.editorFilesId = payload;
    },
    // 设置树展开
    expand: (state, payload) => {
      state.defaultExpanded.push(payload);
    },
    // 设置树关闭
    collapse: (state, payload) => {
      state.defaultExpanded.remove(payload);
    },
    // 设置是否有可下载文件
    setDownloadFile: (state, payload) => {
      if (typeof payload === 'string' && payload === 'shortly') {
        state.downloadFile = null;
        return;
      }
      setTimeout(() => {
        state.downloadFile = payload;
      }, 100);
    },
    setUploadNode: (state, payload) => {
      state.uploadNode = payload;
    },
    // 展示图片弹窗
    showMatlabImg: (state, payload) => {
      if (state.isImgReuseWindow === false || state.matlabImgJsonIndex.length === 0) {
        state.isShowMatlabImg.push(payload.isShow);
        state.matlabImgJson.push(payload.json);
        state.matlabImgJsonIndex.push(state.matlabImgJson.length - 1);
        // console.log('test1');
      } else {
        var index = state.matlabImgJsonIndex[state.matlabImgJsonIndex.length - 1];
        Vue.set(state.matlabImgJson, index, payload.json);
        // state.matlabImgJson[index] = payload.json;
        // console.log('test2');
      }
    },
    // 不展示图片弹窗
    closeMatlabImg: (state, payload) => {
      // state.isShowMatlabImg.splice(payload.id, 1);
      // state.matlabImgJson.splice(payload.id, 1);
      state.matlabImgJsonIndex = state.matlabImgJsonIndex.filter(x => x !== payload.id);
      Vue.set(state.isShowMatlabImg, payload.id, false);
      // state.isShowMatlabImg[payload.id] = false;
    },
    setImgReuseWindow: (state, payload) => {
      state.isImgReuseWindow = payload.isReuse;
    },
    // 展示绘图目录
    showDrawList: (state, payload) => {
      state.isShowDrawList = payload.isShow;
    },
    // 展示选择变量窗口
    showChooseVariable: (state, payload) => {
      state.isShowChooseVariable = payload.isShow;
    },
    // 设置命令行显示
    setTerm: (state, payload) => {
      state.termWrite = payload;
    },
    // 设置命令行调用
    setTermCall: (state, payload) => {
      state.termCall = payload;
    },
    // 调用命令行命令
    termCall: (state, payload) => {
      state.termCall(payload);
    },
    clearVariables: (state) => {
      state.variableArray = [];
      state.selectedVars = [];
      removeVariableTabs(state);
    },
    setSelectedVars: (state, payload) => {
      state.selectedVars = payload;
    },
    setVariableArray: (state, payload) => {
      state.variableArray = payload;
    }
  },

  actions: {
    // 获取项目数据
    getAll: async({ commit }) => {
      const data = await userProjectGetAll();
      if (data.projects instanceof Array) {
        data.projects.forEach((item) => {
          item.id = item.projectId;
          item.label = item.projectName;
          item.isFile = false;
          item.children = item.filePathJson ? JSON.parse(item.filePathJson) : [];
        });
      } else {
        data.projects = [];
      }
      commit('setTreeData', data.projects);
      commit('setFileList');
    },

    // 添加项目
    append: async({ state }, project) => {
      if (!project.fatherId && !project.projectId) {
        const resp = await userProjectSave({ projectName: project.label, filePathJson: '' });
        if (resp.projectId) {
          project.projectId = resp.projectId;
          project.projectName = project.label;
          delete project.tmpProjectIcon;
        }
      } else {
        if (project.projectId) {
          await userProjectUpdate({
            projectId: project.projectId,
            projectName: project.label,
            filePathJson: JSON.stringify(project.children)
          });
          return;
        }
        const obj = state.originTreeData.find(item => {
          return item.projectId === project.fatherId;
        });
        if (obj) {
          await userProjectUpdate({
            projectId: obj.projectId,
            projectName: obj.label,
            filePathJson: JSON.stringify(obj.children)
          });
        }
      }
    },

    // 删除项目
    remove: async({ state, commit }, project) => {
      if (project.projectId) {
        await userProjectDelete({ projectId: project.projectId });
        if (project.projectId in state.projectPublicLayer) {
          delete state.projectPublicLayer[project.projectId];
        }
        // 删除工程下所有文件
        deleteMutli(state, project);
      } else {
        const obj = state.originTreeData.find(item => {
          return item.projectId === project.fatherId;
        });
        if (obj) {
          await userProjectUpdate({
            projectId: obj.projectId,
            projectName: obj.projectName,
            filePathJson: JSON.stringify(obj.children)
          });
        }
        // 删除文件夹下所有文件
        deleteMutli(state, project);
        commit(`setLocalEditorFiles`);
      }
    },
    // 创建文件上传到阿里云
    buildFiles: async({ state }, data) => {
      return new Promise((resolve, reject) => {
        state.isUploadFile = true;
        const file = state.editorFiles.find(item => (item.id === state.editorFilesId));
        const name = `${state.matlabFolderName}/${state.username}/` + `${data.path}`;
        putObject(name, data.text || '', data.id + '.py')
          .then((result) => {
            if (data.type === 'update') {
              file.editText = file.editContent;
            }
            resolve(result);
          })
          .catch((err) => {
            reject(err);
          })
          .finally(_ => {
            state.isUploadFile = false;
          });
      });
    },

    // 获取文件
    getFile: async({ state, commit }, data) => {
      if (state.editorFiles.includeKey('id', data.id)) {
        state.editorFilesId = data.id;
        state.toolbarShowTab = 'editor';
        return;
      }
      const name = `${state.matlabFolderName}/${state.username}/` +
        `${data.path}/${data.id}.py`;
      const url = await getObjectUrl(name);
      const resp = await downloadOss(url);
      const reader = new FileReader();
      reader.onload = function() {
        if (typeof reader.result === 'string') {
          add2FileList(state, data);
          commit('setEditorFiles', {
            type: 'add',
            data: {
              ...data,
              editContent: reader.result,
              editText: reader.result,
              display: 'file'
            }
          });
        }
      };
      reader.readAsText(resp);
    },
    // 打开工作区变量
    openVariable: ({ state, commit }, payload) => {
      if (state.editorFiles.includeKey('id', payload.id)) {
        state.editorFilesId = payload.id;
        state.toolbarShowTab = 'variable';
      } else {
        commit('setEditorFiles', {
          type: 'add',
          data: {
            ...payload,
            display: 'variable'
          }
        });
      }
    },
    // 删除工作区变量
    deleteVariable: ({ state, commit }, payload) => {
      if (state.editorFiles.includeKey('id', payload.id)) {
        commit('setEditorFiles', {
          type: 'remove',
          data: {
            ...payload
          }
        });
      }
      const newvariableArray = state.variableArray.filter((values) => {
        return values.Name !== payload.label;
      });
      commit('setVariableArray', newvariableArray);
      commit('setSelectedVars', []);
    },
    // 运行脚本
    // TODO: 和命令行的联动，和绘图的联动等等
    run: async({ state }, data) => {
      return new Promise((resolve, reject) => {
        const project = getProject(state, data);
        userProjectRun({ projectId: project.id, fileId: data.id }).then((response) => {
          console.log(response);
          if (response.errorType) {
            // 此时运行有错误
            // 此时rspString是错误信息，logResult是发生错误之前函数打印出来的日志
            // 往终端写入 response.logResult + response.rspstring
            // TODO：思考当出现错误时，是否需要将logResult和rspString拼接在一起
            state.termWrite(response.logResult + '\n' + response.rspString);
          } else {
            // 往终端写入 response.logResult
            // 此时rspString是JSON，里面有变量信息和fig信息
            state.termWrite(response.logResult);
          }
          resolve(response);
        }).catch((err) => {
          reject(err);
        });
      });
    },
    // 下载文件
    downloadFile: async({ state }) => {
      if (state.downloadFile) {
        const data = state.downloadFile;
        const name = `${state.matlabFolderName}/${state.username}/` +
          `${data.path}/${data.id}.py`;
        const url = await getObjectUrl(name, data.label);
        window.open(url);
      }
    },
    // TODO: 上传文件放在后端做
    uploadFile: ({ state, dispatch }, file) => {
      return new Promise((resolve, reject) => {
        if (file) {
          const data = state.uploadNode;
          const folder = data.projectName ? data.projectName : `${data.path}/${data.label}`;
          const ossDir = `${state.matlabFolderName}/${state.username}/${folder}`;
          const child = data.children.find((item) => { return item.label === file.name; });
          if (child) {
            MessageBox.confirm(`此操作将替换文件${child.label}, 是否继续?`, '提示', {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            }).then(() => {
              putObject(ossDir, new File([file], child.id + '.py', { type: file.type })).then((res) => {
                resolve(res);
              }).catch((err) => {
                reject(err);
              });
            }).catch((err) => {
              reject(err);
            });
          } else {
            const newChild = {
              isEditName: false,
              id: file.name,
              label: file.name,
              isFirstBuild: true,
              hadRun: false,
              isFile: true
            };
            newChild.fatherId = data.projectId || data.fatherId;
            newChild.path = data.path ? `${data.path}/${data.label}` : data.label;
            data.children.unshift(newChild);
            dispatch('append', newChild).then(() => {
              putObject(ossDir, new File([file], newChild.id + '.py', { type: file.type })).then((res) => {
                resolve(res);
              }).catch((err) => {
                reject(err);
              });
            }).catch((err) => {
              reject(err);
            });
          }
        }
      });
    },
    runTerminalCode: async({ state, dispatch }, data) => {
      const { TerminalCode, TerminalWrite, TerminalOp } = data;
      // 创建一个默认的命令行代码工程
      const TerminalProject = {
        id: getRandomLetter() + getUuid(16),
        label: `User${state.username}_TerminalProject`,
        hadRun: false,
        children: [],
        isFile: false
      };
      state.termProject = TerminalProject;
      const resp = await userProjectSave({ projectName: TerminalProject.label, filePathJson: '' });
      if (resp.projectId) {
        TerminalProject.projectId = resp.projectId;
        TerminalProject.projectName = TerminalProject.label;
      }
      // 创建一个默认的命令行代码脚本
      const TerminalScript = {
        id: getRandomLetter() + getUuid(16),
        label: `User${state.username}_TerminalScript.py`,
        isTerminalScript: true,
        TerminalWrite: TerminalWrite,
        hadRun: false,
        isFile: true,
        fatherId: TerminalProject.projectId,
        path: TerminalProject.label,
        TerminalOp: TerminalOp
      };
      TerminalProject.children.unshift(TerminalScript);
      await userProjectUpdate({
        projectId: TerminalProject.projectId,
        projectName: TerminalProject.label,
        filePathJson: JSON.stringify(TerminalProject.children)
      });
      // 上传文件到阿里云OSS
      state.isUploadFile = true;
      const name0 = `${state.matlabFolderName}/${state.username}/` +
      `${TerminalScript.path}`;
      await putObject(name0, TerminalCode || '', TerminalScript.id + '.py')
        .catch((err) => {
          console.error(err);
        })
        .finally(_ => {
          state.isUploadFile = false;
        });
      // 运行代码文件
      await dispatch('run', TerminalScript)
        .finally(_ => {
          // 执行完毕后删除工程文件
          state.termProject = null;
          userProjectDelete({ projectId: TerminalProject.projectId });
          if (TerminalScript.hadRun) {
            const name_0 = `${state.matlabFolderName}/${state.username}/` +
              `${TerminalScript.path}/${TerminalScript.id}.zip`;
            deleteObject(name_0);
          }
          const name_1 = `${state.matlabFolderName}/${state.username}/` +
            `${TerminalScript.path}/${TerminalScript.id}.py`;
          deleteObject(name_1);
        });
    }
  }
};

// 后退栈赋值
function addNavigator_back(state, data) {
  // console.log('addNavigator_back');
  // console.log('data.breadcrum', JSON.stringify(data.breadcrumb));
  // console.log('before: navList', JSON.stringify(state.navigator.back_navList));
  state.navigator.back_navList.push({
    breadcrumb: JSON.parse(JSON.stringify(data.breadcrumb)),
    showTreeData: data.showTreeData
  });
  state.navigator.back_pointer += 1;
}

// 设置breadPath
function setBreadPath(state) {
  if (state.breadcrumb.length > 0) {
    const b = state.breadcrumb[state.breadcrumb.length - 1];
    state.breadPath = state.username + '/' + (b.path ? `${b.path}/${b.label}` : b.label);
  } else {
    state.breadPath = state.username;
  }
}

// 添加最近的文件浏览记录
function add2FileList(state, payload) {
  if (!state.fileList.find((item) => { return item.id === payload.id; })) {
    state.fileList.push(payload);
  }
}

// 删除最近的文件浏览记录
function removeFromFileList(state, id) {
  state.fileList.remove((item) => {
    return item.id === id;
  });
}

function removeFromEditor(state, id) {
  const index = state.editorFiles.findIndex((item) => { return item.id === id; });
  state.editorFiles.remove(function(item) { return item.id === id; });
  if (state.editorFiles.length === 0) {
    state.editorFilesId = '';
    state.toolbarShowTab = 'main';
  } else if (state.editorFilesId === id) {
    state.editorFilesId = index === 0 ? state.editorFiles[0].id : state.editorFiles[index - 1].id;
  }
}

function removeVariableTabs(state) {
  const newTabs = [];
  let id = '';
  for (const tab of state.editorFiles) {
    if (tab.display !== 'variable') {
      newTabs.push(tab);
      if (tab.id === state.editorFilesId) {
        id = tab.id;
      }
    }
  }
  if (newTabs.length === 0) {
    state.editorFilesId = '';
    state.toolbarShowTab = 'main';
  } else {
    state.editorFilesId = id;
  }
  state.editorFiles = newTabs;
}

// 批量删除文件
function deleteMutli(state, project) {
  if (project.isFile) {
    if (project.hadRun) {
      const name = `${state.matlabFolderName}/${state.username}/` +
        `${project.path}/${project.id}.zip`;
      deleteObject(name);
    }
    const name2 = `${state.matlabFolderName}/${state.username}/` +
      `${project.path}/${project.id}.py`;
    deleteObject(name2);
    removeFromFileList(state, project.id);
    removeFromEditor(state, project.id);
    return;
  }
  const data = {
    path: [],
    projectPath: []
  };
  deleteProjectFiles(state, project.children, data);
  deleteObjectMulti(data.path);
}

function deleteProjectFiles(state, project, data) {
  project.map((item) => {
    if (item.isFile) {
      if (item.hadRun) {
        const name = `${state.matlabFolderName}/${state.username}/` +
          `${item.path}/${item.id}.zip`;
        data.path?.push(name);
        data.projectPath?.push({ name, id: item.id });
      }
      const name2 = `${state.matlabFolderName}/${state.username}/` +
        `${item.path}/${item.id}.py`;
      data.fileIds?.push(item.id);
      data.path?.push(name2);
      data.files?.push(item);
      removeFromFileList(state, item.id);
      removeFromEditor(state, item.id);
    } else {
      if (item.children.length) {
        deleteProjectFiles(state, item.children, data);
      }
    }
  });
}

// 获取文件夹下所有文件
function getProjectFiles(state, project, data) {
  project.forEach((item) => {
    if (item.isFile) {
      if (item.hadRun) {
        const name = `${state.matlabFolderName}/${state.username}/` +
          `${item.path}/${item.id}.zip`;
        data.path?.push(name);
        data.projectPath?.push({ name, id: item.id });
      }
      const name2 = `${state.matlabFolderName}/${state.username}/` +
        `${item.path}/${item.id}.py`;
      data.fileIds?.push(item.id);
      data.path?.push(name2);
      data.files?.push(item);
    } else {
      if (item.children.length) {
        getProjectFiles(state, item.children, data);
      }
    }
  });
}

function getProject(state, file) {
  const obj = file.isTerminalScript ? state.termProject : state.originTreeData.find(item => (item.projectId === file.fatherId));
  if (!obj) {
    throw new Error('工程不存在!');
  }
  return obj;
}

export default matlab;
